package com.zego.wawaji.ui.play;

import android.content.Context;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.zego.wawaji.R;
import com.zego.wawaji.base.module.ModuleMgr;
import com.noble.library.observer.MsgMgr;
import com.zego.wawaji.base.observer.MsgType;
import com.noble.library.observer.PObserver;
import com.zego.wawaji.base.toast.PToast;
import com.zego.wawaji.http.request.HttpResponse;
import com.zego.wawaji.http.request.RequestComplete;
import com.zego.wawaji.http.request.UrlParam;
import com.zego.wawaji.third.image.ImageLoader;
import com.zego.wawaji.third.zego.im.callback.ZegoLivePlayerCallback;
import com.zego.wawaji.third.zego.im.listener.ZegoListener;
import com.zego.wawaji.ui.UIShow;
import com.zego.wawaji.ui.base.BasePanel;
import com.zego.wawaji.ui.base.horizontal.HorizontalListView;
import com.zego.wawaji.ui.bean.wawa.WawaJi;
import com.zego.wawaji.ui.view.marquee.LMarqueeFactory;
import com.zego.wawaji.ui.view.marquee.LMarqueeView;
import com.zego.wawaji.ui.view.marquee.TipsMarqueeView;
import com.zego.wawaji.wawaji_client.cmd.CommandUtil;
import com.zego.wawaji.wawaji_client.play.BoardState;
import com.zego.wawaji.wawaji_client.play.PlayStatus;
import com.zego.zegoliveroom.ZegoLiveRoom;
import com.zego.zegoliveroom.constants.ZegoVideoViewMode;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 游戏页头部布局
 * Created by Su on 2017/11/25.
 */
public class PlayHead extends BasePanel implements View.OnClickListener, PObserver, RequestComplete {
    private WawaJi mRoom;
    private ZegoLiveRoom mZegoLiveRoom;
    private List<ZegoStream> mListStream = new ArrayList<>();

    private TextView mTvStreamSate;         // 展示拉流成功失败结果
    private int mSwitchCameraTimes = 0;     // 切换摄像头次数, 重定义方向键
    private TextView mTvRoomUserCount;      // 房间人数
    private TextView mTvQueueUserCount;     // 排队人数
    private int queueCount;                 // 排队人数
    private RelativeLayout payInfo;         // 底部价格展示
    private ImageView ivRoomStatus;         // 房间状态图片展示
    private ImageView playHead;             // 正在游戏用户头像
    private LMarqueeView lMarqueeView;      // 提示跑马灯
    private LMarqueeFactory<LinearLayout, String> marqueeView;

    private RecyclerView recyclerView;      // 消息列表展示
    private PlaylistAdapter msgAdapter;

    // 预约头像
    private HorizontalListView recyclerHead;
    private HoriQueueAdapter queueAdapter;
    private List<String> heads = new ArrayList<>();

    public PlayHead(Context context, WawaJi mRoom, ZegoLiveRoom mZegoLiveRoom) {
        super(context);
        setContentView(R.layout.play_head_panel);
        this.mRoom = mRoom;
        this.mZegoLiveRoom = mZegoLiveRoom;

        initStream();
        initView();
    }

    private void initView() {
        initMsgList();
        ModuleMgr.getWawaMgr().reqGetMsg(mRoom.getId(), this);
        MsgMgr.getInstance().attach(this);

        // 预约头像
        recyclerHead = (HorizontalListView) findViewById(R.id.queue_list);
        recyclerHead.setItemMargin(2);
        queueAdapter = new HoriQueueAdapter(getContext(), heads);
        recyclerHead.setAdapter(queueAdapter);

        playHead = (ImageView) findViewById(R.id.play_head);
        mTvRoomUserCount = (TextView) findViewById(R.id.tv_room_user_count);
        mTvQueueUserCount = (TextView) findViewById(R.id.tv_room_queue_count);
        mTvStreamSate = (TextView) findViewById(R.id.tv_stream_state);
        mTvStreamSate.setText(mListStream.get(0).getStateString());
        ivRoomStatus = (ImageView) findViewById(R.id.iv_room_status);
        payInfo = (RelativeLayout) findViewById(R.id.play_info_container);
        findViewById(R.id.ibtn_send_msg).setOnClickListener(this);
        findViewById(R.id.btn_back).setOnClickListener(this);

        marqueeView = new TipsMarqueeView(getContext());
        lMarqueeView = (LMarqueeView) findViewById(R.id.marquee);
        marqueeView.setData(mRoom.getTipsList());
        lMarqueeView.setAnimInAndOut(R.anim.bottom_in, R.anim.top_out);
        lMarqueeView.setMarqueeFactory(marqueeView);
        lMarqueeView.startFlipping();

        initFloat();
        initPlayBg();
    }

    /**
     * 背景音乐开关
     */
    public boolean isPlaying = true;

    private void initPlayBg() {
        LinearLayout switch_bgm = (LinearLayout) findViewById(R.id.ibtn_switch_bgm);
        final ImageView ivBgm = (ImageView) findViewById(R.id.iv_switch_bgm);
        switch_bgm.setOnClickListener(v -> {
            if (isPlaying) {
                isPlaying = false;
                ivBgm.setBackgroundResource(R.drawable.play_bgm_no);
                PlayHelper.stopPlay();
            } else {
                isPlaying = true;
                ivBgm.setBackgroundResource(R.drawable.play_bgm);
                PlayHelper.playSound();
            }
        });
    }

    /**
     * 领币悬浮
     */
    private void initFloat() {
        final RelativeLayout inviteLayout = (RelativeLayout) findViewById(R.id.rl_invite);
        findViewById(R.id.btn_float).setOnClickListener(v -> UIShow.showInviteAct(getActivity()));
        findViewById(R.id.btn_close).setOnClickListener(v -> inviteLayout.setVisibility(View.INVISIBLE));
    }

    /**
     * 房间状态
     *
     * @param type 0 空闲， 1 游戏中
     */
    private void roomStatus(int type) {
        if (type != 0) { // 游戏中
            ivRoomStatus.setImageResource(R.drawable.room_status_play);
            return;
        }
        ivRoomStatus.setImageResource(R.drawable.room_status_free);
        ImageLoader.loadCircleAvatar(getContext(), R.drawable.play_room_head, playHead);
    }

    /**
     * loginRoom之后
     */
    public void netStatus() {
        mZegoLiveRoom.startPlayingStream(mListStream.get(0).streamID, mListStream.get(0).textureView);
        mZegoLiveRoom.setViewMode(ZegoVideoViewMode.ScaleAspectFit, mListStream.get(0).streamID);
        mZegoLiveRoom.setPlayVolume(100, mListStream.get(0).streamID);

        mZegoLiveRoom.setViewMode(ZegoVideoViewMode.ScaleAspectFill, mListStream.get(0).streamID);
//        mZegoLiveRoom.setViewRotation(90, mListStream.get(0).streamID);

//        mZegoLiveRoom.startPlayingStream(mListStream.get(1).streamID, mListStream.get(1).textureView);
//        mZegoLiveRoom.setViewMode(ZegoVideoViewMode.ScaleAspectFit, mListStream.get(1).streamID);
//        mZegoLiveRoom.setPlayVolume(0, mListStream.get(1).streamID);
//
//        mZegoLiveRoom.setViewMode(ZegoVideoViewMode.ScaleAspectFill, mListStream.get(1).streamID);
//        mZegoLiveRoom.setViewRotation(180, mListStream.get(1).streamID);
    }

    private void initStream() {
        if (mRoom != null) {
            ZegoStream zegoStream1 = new ZegoStream();
            zegoStream1.streamID = mRoom.getStream1_id();
            zegoStream1.textureView = (TextureView) findViewById(R.id.textureview1);
            zegoStream1.stateStrings = getContext().getResources().getStringArray(R.array.video1_state);
            mListStream.add(zegoStream1);

//            ZegoStream zegoStream2 = new ZegoStream();
//            zegoStream2.streamID = mRoom.getStream2_id();
//            zegoStream2.textureView = (TextureView) findViewById(R.id.textureview2);
//            zegoStream2.stateStrings = getContext().getResources().getStringArray(R.array.video2_state);
//            mListStream.add(zegoStream2);
            return;
        }
        PToast.showShort("流信息数量错误, 请重新开始");
        getActivity().finish();
    }

    public void setupCallbacks(ZegoListener listener) {
        mZegoLiveRoom.setZegoLivePlayerCallback(new ZegoLivePlayerCallback(listener));
    }

    public void refreshVideoSizeChangedTo(String streamID, int i, int i1) {
        for (ZegoStream zegoStream : mListStream) {
            if (zegoStream.streamID.equals(streamID)) {
                zegoStream.state = ZegoStream.STREAM_STATE_SUCCESS;
                break;
            }
        }

        int currentShowIndex = mSwitchCameraTimes % 2;
        if (mListStream.get(currentShowIndex).streamID.equals(streamID)) {
            mTvStreamSate.setVisibility(View.GONE);
            mListStream.get(currentShowIndex).textureView.setVisibility(View.VISIBLE);
        }
    }

    /**
     * 游戏者状态改变
     */
    public void refreshPlayStateUpdate(int errCode, String streamID) {
        int currentShowIndex = mSwitchCameraTimes % 2;
        if (errCode != 0) {
            for (ZegoStream zegoStream : mListStream) {
                if (zegoStream.streamID.equals(streamID)) {
                    zegoStream.state = ZegoStream.STREAM_STATE_FAIL;
                    break;
                }
            }

            // 拉流失败， 展示失败状态
            if (mListStream.get(currentShowIndex).streamID.equals(streamID)) {
                mTvStreamSate.setText(mListStream.get(currentShowIndex).getStateString());
                mTvStreamSate.setVisibility(View.VISIBLE);
            }
        }
    }

    /**
     * 刷新在线人数
     */
    public void refreshUserCount(int total) {
        mTvRoomUserCount.setText(getContext().getString(R.string.room_user_count, total + ""));
    }

    /**
     * 刷新排队人数
     */
    public void refreshQueueCount(int total) {
        this.queueCount = total;
        mTvQueueUserCount.setText(total + "人排队");
        if (queueCount <= 0)
            recyclerHead.setVisibility(View.GONE);
        else
            recyclerHead.setVisibility(View.VISIBLE);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.ibtn_send_msg:  // 发送消息
                ((PlayActivity) getActivity()).showInputPanel();
                break;

            case R.id.btn_back:
                if (logout())
                    getActivity().finish();
                break;
        }
    }

    /**
     * 退出页面检测游戏状态
     */
    public boolean logout() {
        if (PlayStatus.getCurrentBoardSate() == BoardState.Applying
                || PlayStatus.getCurrentBoardSate() == BoardState.WaitingBoard) {
            CommandUtil.getInstance().cancelApply();
            return true;
        }

        if (PlayStatus.getCurrentBoardSate() == BoardState.WaitingReplay) {
            CommandUtil.getInstance().confirmBoard(PlayHelper.rspSeq, "", 0, null);
            return true;
        }

        if (PlayStatus.getCurrentBoardSate() == BoardState.Boarding ||
                PlayStatus.getCurrentBoardSate() == BoardState.Boarding ||
                PlayStatus.getCurrentBoardSate() == BoardState.WaitingGameResult) {
            AlertDialog dialog = new AlertDialog.Builder(getActivity()).setMessage("正在游戏中，无法退出游戏！").setTitle("提示").setNegativeButton("确定", (dialog1, which) -> dialog1.dismiss()).create();
            dialog.show();
            return false;
        }
        return true;
    }

    private List<String> msgList;
    private long msgSize = -1;

    /**
     * 消息列表展示
     */
    private void initMsgList() {
        recyclerView = (RecyclerView) findViewById(R.id.list_msg);
        LinearLayoutManager manager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(manager);
        msgAdapter = new PlaylistAdapter();
        msgList = Collections.synchronizedList(new ArrayList<String>());
        recyclerView.setAdapter(msgAdapter);
        msgAdapter.setList(msgList);
    }


    @Override
    public void onMessage(String key, Object value) {
        switch (key) {
            case MsgType.MT_Room_Status:
                roomStatus((Integer) value);
                refreshQueueCount((Integer) value);
                break;

            case MsgType.MT_Playing_Status:
                payInfo.setVisibility((boolean) value ? View.INVISIBLE : View.VISIBLE);

                if ((boolean) value) {  // 自己在玩，不会收到房间消息，所以手动改变状态
                    ivRoomStatus.setImageResource(R.drawable.room_status_play);
                    ImageLoader.loadCircleAvatar(getContext(), ModuleMgr.getCenterMgr().getMyInfo().getAvatar(), playHead);
                }
                break;

            case MsgType.MT_Msg_Receive:  // 接收消息
                try {
                    String msg = (String) value;
                    if (TextUtils.isEmpty(msg)) return;
                    msgList.add(msg);
                    msgAdapter.notifyItemInserted(msgList.size() - 1);
                    recyclerView.smoothScrollToPosition(msgList.size() - 1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;

            case MsgType.MT_Queue_Head:
                heads = (List<String>) value;
                if (heads == null) return;
                if (heads.size() > 0) {  // 取预约队列第一个人
                    ImageLoader.loadCircleAvatar(getContext(), heads.get(0), playHead);
                }
                queueAdapter.setList(heads);
                break;

        }
    }

    /**
     * 退出停止拉流
     */
    public void doLogout() {
        updateMsg();
        MsgMgr.getInstance().detach(this);
        mZegoLiveRoom.stopPlayingStream(mListStream.get(0).streamID);
        //mZegoLiveRoom.stopPlayingStream(mListStream.get(1).streamID);
        mZegoLiveRoom.stopPublishing();
    }

    private void updateMsg() {
        if (msgSize == msgList.size()) { // 无消息变化，不调用更新接口
            return;
        }

        int size = msgList.size();
        if (size > 10) {  // 最多存储10条
            msgList = msgList.subList(size - 10, msgList.size());
        }
        String msgJson = JSON.toJSONString(msgList);
        ModuleMgr.getWawaMgr().reqUpdateMsg(mRoom.getId(), msgJson);
    }

    @Override
    public void onRequestComplete(HttpResponse response) {
        if (response.getUrlParam() == UrlParam.reqGetMsg) {
            if (!response.isOk()) return;

            JSONObject jsonObject = response.getResponseObject();
            initMsgJson(jsonObject.optString("MsgJson"));
        }
    }

    /**
     * 初始化存储聊天消息
     */
    private void initMsgJson(String msgJson) {
        if (TextUtils.isEmpty(msgJson)) return;
        try {
            JSONArray jsonArray = new JSONArray(msgJson);

            if (jsonArray == null) return;

            for (int i = 0; i < jsonArray.length(); i++) {
                msgList.add(jsonArray.optString(i));
            }
            msgSize = msgList.size();
            msgAdapter.notifyDataSetChanged();
            recyclerView.scrollToPosition(msgAdapter.getItemCount() - 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
